parser grammar VhdlParser;
 
options {
  language = Java;
  tokenVocab = VhdlLexer;
  output = AST;
}

@header {
package org.moflon.moca.vhdl.parser; 
}
// parser rules: 
main: (declaration SEMICOLON)* -> ^(VHDL declaration*); 

declaration: (entity -> entity | architecture -> architecture); 

entity: ENTITY ID IS port_clause? END ENTITY? ID? -> ^(ENTITY ID port_clause?);

port_clause: PORT OPEN_PAREN (p+=port SEMICOLON)* CLOSE_PAREN SEMICOLON -> ($p)+;

port: ID COLON DIRECTION ID -> ^(PORT ID DIRECTION ID);

architecture: ARCHITECTURE ID OF type=ID IS (
  BEGIN (var=ID (ASSIGNMENT logic_expression SEMICOLON (logic_statement)* -> ^(GATE $type ^($var logic_expression) logic_statement*) | 
  PORT_MAP OPEN_PAREN port_mappings CLOSE_PAREN SEMICOLON (connection_statement)* -> ^(BLOCK $type ^($var port_mappings) connection_statement*))) |
  signal+ BEGIN connection_statement* -> ^(BLOCK $type signal+ connection_statement*)
) END ID?;

signal: SIGNAL ID COLON ID SEMICOLON -> ^(SIGNAL ID ID);

/*
architecture_without_signal: BEGIN (statement SEMICOLON)* END ID? -> ^(statement)*;
statement: (logic_statement -> ^(logic_statement) | connection_statement -> ^(connection_statement));
*/

logic_statement: ID ASSIGNMENT logic_expression SEMICOLON -> ^(ID logic_expression);
logic_expression: NOT ID -> ^(NOT ID) | ID AND ID -> ^(AND ID ID)| ID OR ID -> ^(OR ID ID);

connection_statement: ID PORT_MAP OPEN_PAREN port_mappings CLOSE_PAREN SEMICOLON -> ^(ID port_mappings);
port_mappings: port_mapping (COMMA port_mapping)* -> (port_mapping)+;
port_mapping: ID MAP_SIGN ID -> ^(MAP_SIGN ID ID);

// Gate1: AND_GATE port map (A=>input1, B=>input2, F1=>wire)

// architecture identifier of entity_name is architecture_declarative_part begin architecture_statement_part end [ architecture ] [ architecture_simple_name ] ;

